﻿using System;
using System.Collections.Generic;
using System.DrawingCore;
using System.DrawingCore.Imaging;
using System.IO;
using System.Linq;
using System.Net;
using System.Threading.Tasks;
using System.Web;
using BCCommon;
using BCCommon.Enums;
using BCCommon.PaymentEnums;
using BCDto.Common.Payment.Payment;
using BCService.Common.Payment.Payment;
using BCService.Common.Payment.PaymentBusiness;
using BCService.Common.Payment.PaymentCallbackRecord;
using BCService.Common.Payment.PaymentRecord;
using BCService.Website.User;
using BCTMSRESTful.Configs;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;

// For more information on enabling Web API for empty projects, visit https://go.microsoft.com/fwlink/?LinkID=397860

namespace BCTMSRESTful.Controllers.Anonymous
{
    /// <summary>
    /// 官网支付接口
    /// </summary>
    [Route("api/v1/[controller]")]
    public class WebsitePaymentsController : WebsiteBaseController
    {
        private readonly IPaymentService paymentService;
        private readonly IUserService userService;
        private readonly ICommonPaymentCallbackRecordService commonPaymentCallbackRecordService;
        private readonly ICommonPaymentRecordService commonPaymentRecordService;
        private readonly IPaymentBusinessService paymentBusinessService;
        private readonly IConfiguration configuration;
        public WebsitePaymentsController(IPaymentService paymentService,
            IUserService userService,
            ICommonPaymentCallbackRecordService commonPaymentCallbackRecordService,
            ICommonPaymentRecordService commonPaymentRecordService,
            IPaymentBusinessService paymentBusinessService,
            IConfiguration configuration)
        {
            this.paymentService = paymentService;
            this.userService = userService;
            this.commonPaymentCallbackRecordService = commonPaymentCallbackRecordService;
            this.commonPaymentRecordService = commonPaymentRecordService;
            this.paymentBusinessService = paymentBusinessService;
            this.configuration = configuration;
        }
        #region 获取支付渠道
        /// <summary>
        /// 获取支付渠道
        /// </summary>
        /// <param name="sourceAppType">应用类型</param>
        /// <param name="flowType">业务类型</param>
        /// <param name="osType">系统类型</param>
        /// <response code="200">获取支付渠道列表。</response>
        /// <returns></returns>
        [HttpGet("[action]/{app_type}/{order_type}/{os_type}")]
        [ProducesResponseType(typeof(IEnumerable<ChannelDto>), 200)]
        public IActionResult Channels([FromRoute(Name = "app_type")]SourceAppType sourceAppType,
            [FromRoute(Name = "order_type")]FlowType flowType,
            [FromRoute(Name = "os_type")]SourceOSType osType)
        {
            var result = this.paymentService.GetChannels(sourceAppType, flowType, osType,UserInfo);
            return this.Ok(result);
        }
        #endregion

        #region 创建销售合同支付记录并获取支付二维码
        /// <summary>
        /// 创建销售合同支付记录并获取支付二维码（网页使用）
        /// </summary>
        /// <param name="requestDto">支付请求</param>
        /// <response code="201">添加销售合同成功</response>
        /// <response code="400">请求参数或输入的数据不正确。</response>
        /// <response code="500">服务器发生错误。</response>
        /// <response code="501">某些功能尚未实现。</response>
        /// <returns></returns>
        [HttpPost("[action]")]
        [Log("创建销售合同支付记录并获取支付二维码（网页使用）")]
        [ProducesResponseType(typeof(string), 201)]
        public IActionResult QRCode([FromBody]PaymentRequestDto requestDto)
        {
            var channelService = this.paymentService.GetChannelService(requestDto.AppType, requestDto.ChannelType, requestDto.OSType);
            var subject = this.paymentBusinessService.GetPaymentSubject(requestDto,out decimal amount);
            var paymentDto = channelService.GenerateQRCode(requestDto.AppType, requestDto.OrderType, subject, requestDto.ReferenceNumber, requestDto.OSType, requestDto.DeviceType, requestDto.DeviceId, requestDto.Parameters, amount, null,UserInfo);

            //QRCodeHelper qrGenerator = new QRCodeHelper();
            //QRCodeData qrCodeData = qrGenerator.CreateQrCode(HttpUtility.UrlDecode(paymentDto.Token), QRCodeHelper.ECCLevel.H);
            //QRCode qrCode = new QRCode(qrCodeData);
            //Bitmap qrCodeImage = qrCode.GetGraphic(5);
            //MemoryStream stream = new MemoryStream();
            //qrCodeImage.Save(stream, ImageFormat.Png);

            //return File(stream.ToArray(), "image/png");
            paymentDto.QRUrl = HttpUtility.UrlDecode(paymentDto.Token);
            return Ok(paymentDto);
        }
        #endregion

        #region 创建销售合同支付记录
        /// <summary>
        ///  创建销售合同支付记录(App使用)
        /// </summary>
        /// <param name="requestDto">支付请求</param>
        /// <response code="201">创建销售合同支付记录</response>
        /// <response code="400">请求参数或输入的数据不正确。</response>
        /// <response code="500">服务器发生错误。</response>
        /// <response code="501">某些功能尚未实现。</response>
        /// <returns></returns>
        [HttpPost("[action]")]
        [Log("创建销售合同支付记录(App使用)")]
        [ProducesResponseType(typeof(PaymentDto), 201)]
        public IActionResult PaymentRecord([FromBody]PaymentRequestDto requestDto)
        {
            var channelService = this.paymentService.GetChannelService(requestDto.AppType, requestDto.ChannelType, requestDto.OSType);
            var subject = this.paymentBusinessService.GetPaymentSubject(requestDto, out decimal amount);
            var paymentDto = channelService.TryPay(requestDto.AppType, requestDto.OrderType, subject, requestDto.ReferenceNumber, requestDto.OSType, requestDto.DeviceType, requestDto.DeviceId, requestDto.Parameters, amount, null,this.UserInfo);

            return StatusCode((int)HttpStatusCode.Created, paymentDto);
        }
        #endregion

        #region 查询支付结果
        /// <summary>
        /// 查询支付结果
        /// </summary>
        /// <response code="200">获取支付渠道列表。</response>
        /// <returns></returns>
        [HttpGet("{payment_record_id}")]
        [ProducesResponseType(typeof(PaymentDto), 201)]
        public IActionResult Result([FromRoute(Name = "payment_record_id")]long paymentRecordId)
        {
            var result = this.commonPaymentRecordService.GetPaymentRecord(paymentRecordId);
            return this.Ok(result);
        }
        #endregion
    }
}
